package com.ls.rbac.security;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTPayload;

import com.ls.rbac.entity.User;
import com.ls.rbac.utils.JwtUtils;
import com.ls.rbac.utils.RedisUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * created by liush on 2025/6/27
 **/
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {


    @Resource
    private RedisUtils redisUtils;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        User user = (User) authentication.getPrincipal();
        Map<String, Object> userDetails = new HashMap<>();
        userDetails.put("id", user.getId());
        userDetails.put("username", user.getUsername());
        String token = JwtUtils.createToken(userDetails);
        NumberWithFormat time = (NumberWithFormat) JwtUtils.parseToken(token).getClaim(JWTPayload.EXPIRES_AT);
        LocalDateTime localDateTime = Convert.toLocalDateTime(time);
        //转换成时间戳,上海时间
        long expiresAt = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        String key = "login:" + user.getId();
        long expireTime = expiresAt - System.currentTimeMillis();
        redisUtils.set(key, token, expireTime / 1000);
        String infoKey = "login:info:" + user.getId();
        Map<String, Object> info = new HashMap<>();
        info.put("username", user.getUsername());
        info.put("id", user.getId());
        info.put("isEnabled", user.getIsEnabled());
        info.put("isCredentialsNonExpired", user.getIsCredentialsNonExpired());
        info.put("isAccountNonExpired", user.getIsAccountNonExpired());
        info.put("isAccountNonLocked", user.getIsAccountNonLocked());
        String infoStr = JSONUtil.toJsonStr(info);
        redisUtils.set(infoKey, infoStr,expireTime / 1000);
        Collection<GrantedAuthority> authorities = user.getAuthorities();
        String permissions = authorities.stream().map(GrantedAuthority::getAuthority)
                .collect(Collectors.joining(","));
        redisUtils.set("permissions:" + user.getId(), permissions, expireTime / 1000);
        AuthenticationResult result = new AuthenticationResult(user.getId(), HttpStatus.OK.value(), "登录成功", token, 1000 * 60 * 60L);
        String jsonString = JSONUtil.toJsonStr(result);
        System.out.println("登录成功: \n" + jsonString);
        PrintWriter writer = response.getWriter();
        writer.write(jsonString);
        writer.close();
    }
}